home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 10
/
amigaformatcd10.iso
/
-screenplay-
/
shareware
/
mris 1.1
/
.mris1_1src.lha
/
Errors.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-10
|
21KB
|
797 lines
#ifndef INTUITION_IMAGECLASS_H
#include <intuition/imageclass.h>
#endif
#ifndef INTUITION_GADGETCLASS_H
#include <intuition/gadgetclass.h>
#endif
#ifndef LIBRARIES_IFFPARSE_H
#include <libraries/iffparse.h>
#endif
#ifndef INTUITION_ICCLASS_H
#include <intuition/icclass.h>
#endif
#include <proto/layers.h>
#include <proto/gadtools.h>
#define MYLIB_BOOPSI
#include "xmris.h"
#include "Errors.h"
#include "ConfigScreen.h"
#include "Catalog.h"
/************************************************************************/
#define BUTTON_LEFT 0
#define BUTTON_RIGHT 1
#define BUTTON_UP 2
#define BUTTON_DOWN 3
#define SCROLLER_HORIZONTAL 4
#define SCROLLER_VERTICAL 5
/************************************************************************/
struct Line
{
struct MinNode Node;
/* followed by '\0'-terminated text */
};
/************************************************************************/
struct Window *ErrorWindow;
int ErrorFlag;
/************************************************************************/
static struct MinList Lines=
{
(struct MinNode *)&Lines.mlh_Tail,NULL,(struct MinNode *)&Lines.mlh_Head
};
static WORD MaxWidth;
static UWORD LineCount;
static struct DrawInfo *DrawInfo;
static struct Gadget *Gadgets;
static struct Gadget *VerticalScroller, *HorizontalScroller;
static int UnlockScreen;
/************************************************************************/
static struct TagItem WindowTags[]=
{
{WA_MinWidth, 0}, /* 0 */
{WA_MinHeight, 0}, /* 1 */
{WA_MaxWidth, ~0}, /* 2 */
{WA_MaxHeight, ~0}, /* 3 */
{WA_CustomScreen, (ULONG)NULL}, /* 4 */
{WA_Width, 0}, /* 5 */
{WA_Height, 0}, /* 6 */
{WA_Left, ~0}, /* 7 */
{WA_Top, ~0}, /* 8 */
{WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH | WFLG_NEWLOOKMENUS | WFLG_SIZEBBOTTOM | WFLG_SIZEBRIGHT},
{TAG_DONE}
};
/************************************************************************/
void CloseErrorWindow()
{
if ((struct Screen *)WindowTags[4].ti_Data!=NULL)
{
if (DrawInfo!=NULL)
{
if (Gadgets!=NULL)
{
if (ErrorWindow!=NULL)
{
struct Menu *Menustrip;
if ((Menustrip=ErrorWindow->MenuStrip)!=NULL)
{
ClearMenuStrip(ErrorWindow);
FreeVisualInfo(GTMENU_USERDATA(Menustrip));
FreeMenus(Menustrip);
}
GS_WindowWakeup(ErrorWindow);
assert(WindowTags[5].ti_Tag==WA_Width);
assert(WindowTags[6].ti_Tag==WA_Height);
LockLayerInfo(ErrorWindow->WLayer->LayerInfo);
WindowTags[5].ti_Data=ErrorWindow->Width;
WindowTags[6].ti_Data=ErrorWindow->Height;
WindowTags[7].ti_Data=ErrorWindow->LeftEdge;
WindowTags[8].ti_Data=ErrorWindow->TopEdge;
UnlockLayerInfo(ErrorWindow->WLayer->LayerInfo);
CloseWindowSafely(ErrorWindow);
ErrorWindow=NULL;
}
while (Gadgets!=NULL)
{
struct Gadget *Next;
DisposeObject(Gadgets->UserData);
Next=Gadgets->NextGadget;
DisposeObject(Gadgets);
Gadgets=Next;
}
}
FreeScreenDrawInfo((struct Screen *)WindowTags[4].ti_Data,DrawInfo);
}
if (UnlockScreen)
{
UnlockPubScreen(NULL,(struct Screen *)WindowTags[4].ti_Data);
}
WindowTags[4].ti_Data=(ULONG)NULL;
}
}
/************************************************************************/
/* */
/* Measure width of all text lines, to find maximum width */
/* */
/************************************************************************/
static void CalcMaxWidth(void)
{
struct Line *Line;
for (Line=(struct Line *)Lines.mlh_Head; Line->Node.mln_Succ!=NULL; Line=(struct Line *)Line->Node.mln_Succ)
{
WORD Width;
Width=TextLength(ErrorWindow->RPort,(char *)(Line+1),strlen((char *)(Line+1)));
if (Width>MaxWidth)
{
MaxWidth=Width;
}
}
}
/************************************************************************/
/* */
/* Create & install the clipping region */
/* */
/************************************************************************/
static int InstallClipping(void)
{
struct Region *Region;
if ((Region=NewRegion())!=NULL)
{
struct Rectangle Rectangle;
Rectangle.MinX=ErrorWindow->BorderLeft+ErrorWindow->RPort->TxHeight;
Rectangle.MaxX=ErrorWindow->Width-ErrorWindow->BorderRight-ErrorWindow->RPort->TxHeight-1;
Rectangle.MinY=ErrorWindow->BorderTop+ErrorWindow->RPort->TxHeight/2;
Rectangle.MaxY=ErrorWindow->Height-ErrorWindow->BorderBottom-ErrorWindow->RPort->TxHeight/2-1;
if (OrRectRegion(Region,&Rectangle))
{
InstallClipRegion(ErrorWindow->WLayer,Region);
return TRUE;
}
DisposeRegion(Region);
}
return FALSE;
}
/************************************************************************/
static void RemoveClipping(void)
{
DisposeRegion(InstallClipRegion(ErrorWindow->WLayer,NULL));
}
/************************************************************************/
/* */
/* Redraw the full window. */
/* This just does the rendering, no clipping! */
/* */
/************************************************************************/
static void DrawWindow(void)
{
WORD Y, YMax, X, XMax;
struct RastPort *RastPort;
struct Line *Current;
RastPort=ErrorWindow->RPort;
YMax=ErrorWindow->Height-ErrorWindow->BorderBottom-RastPort->TxHeight/2;
SetABPenDrMd(RastPort,DrawInfo->dri_Pens[TEXTPEN],DrawInfo->dri_Pens[BACKGROUNDPEN],JAM2);
YMax=ErrorWindow->Height-ErrorWindow->BorderBottom-RastPort->TxHeight/2;
Y=ErrorWindow->BorderTop+RastPort->TxHeight/2-AttrGet((Object *)VerticalScroller,PGA_Top);
Current=(struct Line *)Lines.mlh_Head;
while (Y<0)
{
assert(Current->Node.mln_Succ!=NULL);
Current=(struct Line *)Current->Node.mln_Succ;
Y+=RastPort->TxHeight;
}
X=ErrorWindow->BorderLeft+RastPort->TxHeight-AttrGet((Object *)HorizontalScroller,PGA_Top);
XMax=ErrorWindow->Width-ErrorWindow->BorderRight-RastPort->TxHeight;
while (Current->Node.mln_Succ!=NULL && Y<=YMax)
{
Move(RastPort,X,Y+RastPort->TxBaseline);
Text(RastPort,(char *)(Current+1),strlen((char *)(Current+1)));
if (RastPort->cp_x<=XMax)
{
SetAPen(RastPort,DrawInfo->dri_Pens[BACKGROUNDPEN]);
RectFill(RastPort,RastPort->cp_x,Y,XMax,Y+RastPort->TxHeight-1);
SetAPen(RastPort,DrawInfo->dri_Pens[TEXTPEN]);
}
Y+=RastPort->TxHeight;
Current=(struct Line *)Current->Node.mln_Succ;
}
}
/************************************************************************/
static void RedrawWindow(void)
{
LockLayer(0,ErrorWindow->WLayer);
if (InstallClipping())
{
DrawWindow();
RemoveClipping();
}
UnlockLayer(ErrorWindow->WLayer);
}
/************************************************************************/
static INLINE void MakeMenu(void)
{
static struct NewMenu NewMenu[]=
{
{NM_TITLE,(STRPTR)MSG_GAME_MENU,NULL,0,0,NULL},
{NM_ITEM,(STRPTR)MSG_GAME_FLUSHERRORS_MENU,NULL,0,0,(APTR)MSG_GAME_FLUSHERRORS_MENU},
{NM_ITEM,NM_BARLABEL,NULL,0,0,NULL},
{NM_ITEM,(STRPTR)MSG_GAME_QUIT_MENU,NULL,0,0,(APTR)MSG_GAME_QUIT_MENU},
{NM_TITLE,(STRPTR)MSG_CONFIG_MENU,NULL,0,0,NULL},
{NM_ITEM,(STRPTR)MSG_CONFIG_DISPLAY_SCREEN_MENU,NULL,0,0,(APTR)MSG_CONFIG_DISPLAY_SCREEN_MENU},
{NM_END}
};
struct Menu *Menustrip;
if ((Menustrip=CreateMenustrip(NewMenu))!=NULL)
{
APTR VisualInfo;
assert(WindowTags[4].ti_Tag==WA_CustomScreen);
if ((VisualInfo=GetVisualInfoA((struct Screen *)WindowTags[4].ti_Data,NULL))!=NULL)
{
static struct TagItem TagList[]=
{
{GTMN_NewLookMenus, TRUE},
{TAG_DONE}
};
if (LayoutMenusA(Menustrip,VisualInfo,TagList))
{
SetMenuStrip(ErrorWindow,Menustrip);
GTMENU_USERDATA(Menustrip)=VisualInfo;
return;
}
FreeVisualInfo(VisualInfo);
}
FreeMenus(Menustrip);
}
}
/************************************************************************/
static struct Image *MakeImage(struct Screen *Screen, ULONG Type)
{
return (struct Image *)NewObject(NULL,BOOPSI_sysiclass,
SYSIA_Which, Type,
SYSIA_DrawInfo, DrawInfo,
SYSIA_Size, (Screen->Flags & SCREENHIRES) ? SYSISIZE_MEDRES : SYSISIZE_LOWRES,
TAG_DONE);
}
/************************************************************************/
static void UpdateScrollers(void)
{
SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,
PGA_Total, LineCount*ErrorWindow->RPort->TxHeight,
PGA_Visible, ErrorWindow->Height-ErrorWindow->BorderTop-ErrorWindow->BorderBottom-2*(ErrorWindow->RPort->TxHeight/2),
TAG_DONE);
SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,
PGA_Total, MaxWidth,
PGA_Visible, ErrorWindow->Width-ErrorWindow->BorderLeft-ErrorWindow->BorderRight-2*ErrorWindow->RPort->TxHeight,
TAG_DONE);
}
/************************************************************************/
void OpenErrorWindow(void)
{
if (ErrorWindow==NULL)
{
struct Screen *Screen;
if (display.Screen!=NULL)
{
Screen=display.Screen->Screen;
UnlockScreen=FALSE;
}
else
{
Screen=LockPubScreen(NULL);
UnlockScreen=TRUE;
}
assert(WindowTags[4].ti_Tag==WA_CustomScreen);
WindowTags[4].ti_Data=(ULONG)Screen;
if (Screen!=NULL)
{
if ((DrawInfo=GetScreenDrawInfo(Screen))!=NULL)
{
struct Image *Image;
if ((Image=MakeImage(Screen,SIZEIMAGE))!=NULL)
{
WORD SizingWidth, SizingHeight;
SizingWidth=Image->Width;
SizingHeight=Image->Height;
DisposeObject(Image);
if ((Image=MakeImage(Screen,RIGHTIMAGE))!=NULL)
{
struct Gadget *Gadget;
Gadgets=Gadget=NewObject(NULL,BOOPSI_buttongclass,
GA_RelRight, 1-(SizingWidth+Image->Width),
GA_RelBottom, 1-Image->Height,
GA_BottomBorder, TRUE,
GA_Image, Image,
GA_UserData, Image,
ICA_TARGET, ICTARGET_IDCMP,
GA_ID, BUTTON_RIGHT,
TAG_DONE);
if (Gadget!=NULL && (Image=MakeImage(Screen,LEFTIMAGE))!=NULL)
{
Gadget=NewObject(NULL,BOOPSI_buttongclass,
GA_Previous, Gadget,
GA_RelRight, Gadget->LeftEdge-Image->Width,
GA_RelBottom, Gadget->TopEdge,
GA_BottomBorder, TRUE,
GA_Image, Image,
GA_UserData, Image,
ICA_TARGET, ICTARGET_IDCMP,
GA_ID, BUTTON_LEFT,
TAG_DONE);
if (Gadget!=NULL)
{
Image=NULL;
Gadget=NewObject(NULL,BOOPSI_propgclass,
GA_Previous, Gadget,
PGA_Freedom, FREEHORIZ,
PGA_NewLook, TRUE,
PGA_Borderless, TRUE,
GA_Left, Screen->WBorLeft,
GA_RelBottom, -SizingHeight+Screen->WBorBottom/2+2,
GA_RelWidth, Gadget->LeftEdge-Screen->WBorLeft-1,
GA_Height, SizingHeight-Screen->WBorBottom-2,
GA_BottomBorder, TRUE,
GA_UserData, NULL,
ICA_TARGET, ICTARGET_IDCMP,
GA_ID, SCROLLER_HORIZONTAL,
TAG_DONE);
HorizontalScroller=Gadget;
if (Gadget!=NULL && (Image=MakeImage(Screen,DOWNIMAGE))!=NULL)
{
Gadget=NewObject(NULL,BOOPSI_buttongclass,
GA_Previous, Gadget,
GA_RelRight, 1-Image->Width,
GA_RelBottom, 1-(SizingHeight+Image->Height),
GA_RightBorder, TRUE,
GA_Image, Image,
GA_UserData, Image,
ICA_TARGET, ICTARGET_IDCMP,
GA_ID, BUTTON_DOWN,
TAG_DONE);
if (Gadget!=NULL && (Image=MakeImage(Screen,UPIMAGE))!=NULL)
{
Gadget=NewObject(NULL,BOOPSI_buttongclass,
GA_Previous, Gadget,
GA_RelRight, Gadget->LeftEdge,
GA_RelBottom, Gadget->TopEdge-Image->Height,
GA_RightBorder, TRUE,
GA_Image, Image,
GA_UserData, Image,
ICA_TARGET, ICTARGET_IDCMP,
GA_ID, BUTTON_UP,
TAG_DONE);
if (Gadget!=NULL)
{
WORD TopBorder;
Image=NULL;
TopBorder=Screen->WBorTop+DrawInfo->dri_Font->tf_YSize+1;
Gadget=NewObject(NULL,BOOPSI_propgclass,
GA_Previous, Gadget,
PGA_NewLook, TRUE,
PGA_Borderless, TRUE,
PGA_Top, MAX_WORD,
GA_Top, TopBorder,
GA_RelRight, Screen->WBorRight/2+2-SizingWidth,
GA_RelHeight, Gadget->TopEdge-TopBorder-1,
GA_Width, SizingWidth-Screen->WBorRight-2,
GA_RightBorder, TRUE,
GA_UserData, NULL,
GA_ID, SCROLLER_VERTICAL,
ICA_TARGET, ICTARGET_IDCMP,
TAG_DONE);
VerticalScroller=Gadget;
if (Gadget!=NULL)
{
assert(WindowTags[0].ti_Tag==WA_MinWidth);
WindowTags[0].ti_Data=10*DrawInfo->dri_Font->tf_YSize-HorizontalScroller->Width;
assert(WindowTags[1].ti_Tag==WA_MinHeight);
WindowTags[1].ti_Data=DrawInfo->dri_Font->tf_YSize-VerticalScroller->Height;
if (WindowTags[1].ti_Data<3*DrawInfo->dri_Font->tf_YSize)
{
WindowTags[1].ti_Data=3*DrawInfo->dri_Font->tf_YSize;
}
assert(WindowTags[5].ti_Tag==WA_Width);
if (WindowTags[5].ti_Data<WindowTags[0].ti_Data)
{
WindowTags[5].ti_Data=WindowTags[0].ti_Data+15*DrawInfo->dri_Font->tf_YSize;
}
assert(WindowTags[6].ti_Tag==WA_Height);
if (WindowTags[6].ti_Data<WindowTags[1].ti_Data)
{
WindowTags[6].ti_Data=WindowTags[1].ti_Data;
}
assert(WindowTags[7].ti_Tag==WA_Left);
assert(WindowTags[8].ti_Tag==WA_Top);
if (WindowTags[7].ti_Data==~0)
{
ULONG IntuiLock;
IntuiLock=LockIBase(0);
WindowTags[7].ti_Data=Screen->MouseX;
WindowTags[8].ti_Data=Screen->MouseY;
UnlockIBase(IntuiLock);
WindowTags[7].ti_Data-=WindowTags[5].ti_Data/2;
WindowTags[8].ti_Data-=WindowTags[6].ti_Data/2;
}
ErrorWindow=OpenWindowTags(NULL,
WA_Title, GetString(MSG_ERRORS_TITLE),
WA_Gadgets, Gadgets,
TAG_MORE, WindowTags);
if (ErrorWindow!=NULL)
{
SetFont(ErrorWindow->RPort,DrawInfo->dri_Font);
ErrorWindow->UserPort=&WindowPort;
if (ModifyIDCMP(ErrorWindow,(IDCMP_REFRESHWINDOW |
IDCMP_CLOSEWINDOW |
IDCMP_IDCMPUPDATE |
IDCMP_MENUPICK |
IDCMP_NEWSIZE)))
{
MakeMenu();
CalcMaxWidth();
LockLayer(0,ErrorWindow->WLayer);
if (InstallClipping())
{
UpdateScrollers();
DrawWindow();
RemoveClipping();
}
UnlockLayer(ErrorWindow->WLayer);
if (MiscState.Sleep)
{
GS_WindowSleep(ErrorWindow);
}
return;
}
}
}
}
}
}
}
}
}
DisposeObject(Image);
}
}
CloseErrorWindow();
}
}
}
/************************************************************************/
void DisplayError(LONG TemplateID, ...)
{
char String[ERRORSTRING_LENGTH];
char *Error;
ULONG Length;
if (TemplateID!=0)
{
Error=GS_FormatString(GetString(TemplateID),(&TemplateID)+1,&Length,Locale);
}
else
{
Error=ErrorString(String,*(&TemplateID+1));
Length=strlen(Error);
}
if (Error!=NULL)
{
struct Line *Line;
if ((Line=GS_MemoryAlloc(sizeof(*Line)+Length+1))!=NULL)
{
strcpy((char *)(Line+1),Error);
AddTail((struct List *)&Lines,(struct Node *)&Line->Node);
LineCount++;
if (ErrorWindow!=NULL)
{
if (LineCount*ErrorWindow->RPort->TxHeight+2*(ErrorWindow->RPort->TxHeight/2)+ErrorWindow->BorderTop+ErrorWindow->BorderBottom>MAX_WORD)
{
GS_MemoryFree(RemHead((struct List *)&Lines));
CalcMaxWidth();
}
else
{
WORD Width;
Width=TextLength(ErrorWindow->RPort,(char *)(Line+1),Length);
if (Width>MaxWidth)
{
MaxWidth=Width;
}
}
UpdateScrollers();
}
if (ErrorWindow!=NULL)
{
SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,PGA_Top,MAX_WORD,TAG_DONE);
SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,PGA_Top,0,TAG_DONE);
RedrawWindow();
}
else
{
OpenErrorWindow();
}
ErrorFlag=TRUE;
}
if (TemplateID!=0)
{
GS_MemoryFree(Error);
}
}
}
/************************************************************************/
void FreeErrors(void)
{
struct Line *Line;
while ((Line=(struct Line *)RemHead((struct List *)&Lines))!=NULL)
{
GS_MemoryFree(Line);
}
}
/************************************************************************/
/* */
/* Currently the DOS error codes (ERROR_#?), IFF error codes */
/* (IFFERR_#?) and screen error codes (OSERR_#?) are supported. */
/* */
/************************************************************************/
char *ErrorString(char *String, LONG ErrorCode)
{
if (ErrorCode<0)
{
/* IFF error */
switch (ErrorCode)
{
case IFFERR_NOTIFF:
return GetString(MSG_IFFERR_NOTIFF);
case IFFERR_NOSCOPE:
case IFFERR_MANGLED:
case IFFERR_SYNTAX:
return GetString(MSG_IFFERR_INVALIDIFF);
case IFFERR_NOMEM:
ErrorCode=ERROR_NO_FREE_STORE;
break;
case IFFERR_READ:
return GetString(MSG_IFFERR_READ);
case IFFERR_WRITE:
return GetString(MSG_IFFERR_WRITE);
case IFFERR_SEEK:
return GetString(MSG_IFFERR_SEEK);
}
}
if (ErrorCode<100)
{
/* screen error code */
switch (ErrorCode)
{
case OSERR_NOMEM:
ErrorCode=ERROR_NO_FREE_STORE;
break;
case OSERR_NOCHIPMEM:
return GetString(MSG_OSERR_NOCHIPMEM);
case OSERR_NOMONITOR:
case OSERR_NOCHIPS:
case OSERR_UNKNOWNMODE:
case OSERR_NOTAVAILABLE:
return GetString(MSG_OSERR_INVALIDMODE);
#ifdef DEBUG
case OSERR_PUBNOTUNIQUE:
assert(FALSE);
break;
#endif
case OSERR_TOODEEP:
return GetString(MSG_OSERR_TOODEEP);
}
}
if (ErrorCode==ERROR_UNKNOWN || ErrorCode==0)
{
return GetString(MSG_ERROR_UNKNOWN);
}
/* DOS error code */
Fault(ErrorCode,NULL,String,ERRORSTRING_LENGTH);
return String;
}
/************************************************************************/
void ProcessErrorWindow(struct IntuiMessage *Message)
{
switch (Message->Class)
{
case IDCMP_CLOSEWINDOW:
ReplyMsg(&Message->ExecMessage);
CloseErrorWindow();
return;
case IDCMP_MENUPICK:
{
UWORD Selection;
Selection=Message->Code;
while (Selection!=MENUNULL && !global.quit)
{
struct MenuItem *Item;
Item=ItemAddress(ErrorWindow->MenuStrip,Selection);
switch ((ULONG)GTMENUITEM_USERDATA(Item))
{
case MSG_GAME_QUIT_MENU:
global.quit=TRUE;
break;
case MSG_CONFIG_DISPLAY_SCREEN_MENU:
OpenConfigScreen();
break;
case MSG_GAME_FLUSHERRORS_MENU:
FreeErrors();
goto Redraw;
}
Selection=Item->NextSelect;
}
}
break;
case IDCMP_REFRESHWINDOW:
LockLayerInfo(ErrorWindow->WLayer->LayerInfo);
if (InstallClipping())
{
BeginRefresh(ErrorWindow);
DrawWindow();
EndRefresh(ErrorWindow,TRUE);
RemoveClipping();
}
UnlockLayerInfo(ErrorWindow->WLayer->LayerInfo);
break;
case IDCMP_NEWSIZE:
Redraw:
LockLayer(0,ErrorWindow->WLayer);
SetABPenDrMd(ErrorWindow->RPort,DrawInfo->dri_Pens[BACKGROUNDPEN],0,JAM1);
RectFill(ErrorWindow->RPort,
ErrorWindow->BorderLeft,
ErrorWindow->BorderTop,
ErrorWindow->Width-ErrorWindow->BorderRight-1,
ErrorWindow->Height-ErrorWindow->BorderBottom-1);
if (InstallClipping())
{
UpdateScrollers();
DrawWindow();
RemoveClipping();
}
UnlockLayer(ErrorWindow->WLayer);
break;
case IDCMP_IDCMPUPDATE:
switch (GetTagData(GA_ID,0,(struct TagItem *)Message->IAddress))
{
case SCROLLER_HORIZONTAL:
case SCROLLER_VERTICAL:
RedrawWindow();
break;
case BUTTON_LEFT:
{
WORD Top;
if ((Top=(WORD)AttrGet((Object *)HorizontalScroller,PGA_Top))>0)
{
SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,PGA_Top,Top-1,TAG_DONE);
RedrawWindow();
}
}
break;
case BUTTON_RIGHT:
SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,PGA_Top,AttrGet((Object *)HorizontalScroller,PGA_Top)+1,TAG_DONE);
RedrawWindow();
break;
case BUTTON_UP:
{
WORD Top;
if ((Top=(WORD)AttrGet((Object *)VerticalScroller,PGA_Top))>0)
{
SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,PGA_Top,Top-1,TAG_DONE);
RedrawWindow();
}
}
break;
case BUTTON_DOWN:
SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,PGA_Top,AttrGet((Object *)VerticalScroller,PGA_Top)+1,TAG_DONE);
RedrawWindow();
break;
}
break;
}
ReplyMsg(&Message->ExecMessage);
}